<script setup lang="ts">
import { onMounted, ref, reactive } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, Edit, Delete, Menu as MenuIcon, Folder, Document } from '@element-plus/icons-vue'
import type { MenuVO, MenuAddRequest, MenuUpdateRequest } from '@/api-client/src/api-client/models'
import { getMenuController } from '@/api-client'

// API控制器实例
const menuApi = getMenuController()

// 响应式状态
const loading = ref(false)
const menuList = ref<MenuVO[]>([])
const dialogVisible = ref(false)
const dialogTitle = ref('')
const isEdit = ref(false)

// 表单数据
const formData = reactive<MenuAddRequest | MenuUpdateRequest>({
  id: 0,
  pid: 0,
  name: '',
  icon: '',
  route: '',
  sortId: 0,
})

// 表单验证规则
const rules = {
  name: [
    { required: true, message: '请输入菜单名称', trigger: 'blur' },
    { min: 1, max: 50, message: '长度在 1 到 50 个字符', trigger: 'blur' },
  ],
  pid: [{ required: true, message: '请选择父级菜单', trigger: 'change' }],
}

const formRef = ref()

// 图标选项
const iconOptions = [
  { label: 'Grid', value: 'Grid' },
  { label: 'Money', value: 'Money' },
  { label: 'Location', value: 'Location' },
  { label: 'ChatLineSquare', value: 'ChatLineSquare' },
  { label: 'Tools', value: 'Tools' },
  { label: 'WindPower', value: 'WindPower' },
  { label: 'OfficeBuilding', value: 'OfficeBuilding' },
  { label: 'House', value: 'House' },
  { label: 'User', value: 'User' },
  { label: 'Van', value: 'Van' },
  { label: 'Odometer', value: 'Odometer' },
  { label: 'DataBoard', value: 'DataBoard' },
  { label: 'Setting', value: 'Setting' },
  { label: 'UserFilled', value: 'UserFilled' },
  { label: 'Avatar', value: 'Avatar' },
  { label: 'Menu', value: 'Menu' },
]

// 获取菜单树
const fetchMenuTree = async () => {
  loading.value = true
  try {
    const response = await menuApi.getMenuTree()
    if (response.code === 200 && response.data) {
      menuList.value = response.data
    } else {
      ElMessage.error(response.message || '获取菜单列表失败')
    }
  } catch (error) {
    ElMessage.error('获取菜单列表失败')
    console.error(error)
  } finally {
    loading.value = false
  }
}

// 获取父级菜单选项（只包含一级菜单和二级菜单，用于新建菜单时选择父级）
const getParentMenuOptions = (
  menus: MenuVO[],
  level = 1,
): Array<{ label: string; value: number; disabled?: boolean }> => {
  const options: Array<{ label: string; value: number; disabled?: boolean }> = [
    { label: '顶级菜单', value: 0 },
  ]

  menus.forEach((menu) => {
    if (level <= 2) {
      // 限制只显示到二级菜单
      options.push({
        label: `${'　'.repeat(level - 1)}${menu.name}`,
        value: menu.id || 0,
        disabled: level === 2, // 二级菜单不能再添加子菜单
      })

      if (menu.children && menu.children.length > 0 && level < 2) {
        options.push(...getParentMenuOptions(menu.children, level + 1))
      }
    }
  })

  return options
}

// 添加菜单
const handleAdd = (parentId = 0) => {
  // 检查层级限制
  if (parentId !== 0) {
    const parent = findMenuById(menuList.value, parentId)
    if (parent && parent.pid !== 0) {
      ElMessage.warning('不允许添加三级菜单')
      return
    }
  }

  isEdit.value = false
  dialogTitle.value = '添加菜单'
  Object.assign(formData, {
    pid: parentId,
    name: '',
    icon: '',
    route: '',
    sortId: 0,
  })
  dialogVisible.value = true
}

// 编辑菜单
const handleEdit = (row: MenuVO) => {
  isEdit.value = true
  dialogTitle.value = '编辑菜单'
  Object.assign(formData, {
    id: row.id,
    pid: row.pid,
    name: row.name,
    icon: row.icon,
    route: row.route,
    sortId: row.sortId,
  })
  dialogVisible.value = true
}

// 删除菜单
const handleDelete = async (row: MenuVO) => {
  if (row.children && row.children.length > 0) {
    ElMessage.warning('请先删除子菜单')
    return
  }

  try {
    await ElMessageBox.confirm(`确定要删除菜单 "${row.name}" 吗？`, '确认删除', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    })

    const response = await menuApi.deleteMenu(row.id || 0)
    if (response.code === 200) {
      ElMessage.success('删除成功')
      await fetchMenuTree()
    } else {
      ElMessage.error(response.message || '删除失败')
    }
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('删除失败')
      console.error(error)
    }
  }
}

// 保存菜单
const handleSave = async () => {
  if (!formRef.value) return

  try {
    await formRef.value.validate()

    let response
    if (isEdit.value) {
      response = await menuApi.updateMenu(formData as MenuUpdateRequest)
    } else {
      response = await menuApi.addMenu(formData as MenuAddRequest)
    }

    if (response.code === 200) {
      ElMessage.success(isEdit.value ? '更新成功' : '添加成功')
      dialogVisible.value = false
      await fetchMenuTree()
    } else {
      ElMessage.error(response.message || (isEdit.value ? '更新失败' : '添加失败'))
    }
  } catch (error) {
    console.error(error)
  }
}

// 取消操作
const handleCancel = () => {
  dialogVisible.value = false
  formRef.value?.resetFields()
}

// 查找菜单
const findMenuById = (menus: MenuVO[], id: number): MenuVO | null => {
  for (const menu of menus) {
    if (menu.id === id) {
      return menu
    }
    if (menu.children) {
      const found = findMenuById(menu.children, id)
      if (found) return found
    }
  }
  return null
}

// 组件挂载时获取数据
onMounted(() => {
  fetchMenuTree()
})
</script>

<template>
  <div class="menu-view">
    <div class="page-header">
      <h2 class="page-title">菜单管理</h2>
      <p class="page-description">管理系统菜单结构，支持一级和二级菜单</p>
    </div>

    <el-card class="menu-card" shadow="hover">
      <template #header>
        <div class="card-header">
          <div class="header-content">
            <el-icon class="header-icon"><MenuIcon /></el-icon>
            <span class="card-title">菜单列表</span>
          </div>
          <el-button type="primary" :icon="Plus" @click="handleAdd(0)"> 添加一级菜单 </el-button>
        </div>
      </template>

      <el-table
        :data="menuList"
        style="width: auto"
        v-loading="loading"
        row-key="id"
        :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
        stripe
        :header-cell-style="{ background: '#f8f9fa', color: '#495057' }"
      >
        <el-table-column prop="name" label="菜单名称" width="auto">
          <template #default="{ row }">
            <div class="menu-name">
              <el-icon class="menu-icon">
                <Folder v-if="row.children && row.children.length > 0" />
                <Document v-else />
              </el-icon>
              <span>{{ row.name }}</span>
            </div>
          </template>
        </el-table-column>

        <el-table-column prop="icon" label="图标" width="auto" align="center">
          <template #default="{ row }">
            <el-tag v-if="row.icon" size="small" type="info">{{ row.icon }}</el-tag>
            <span v-else class="text-muted">-</span>
          </template>
        </el-table-column>

        <el-table-column prop="route" label="路由地址" width="auto">
          <template #default="{ row }">
            <el-tag v-if="row.route" size="small" type="success">{{ row.route }}</el-tag>
            <span v-else class="text-muted">-</span>
          </template>
        </el-table-column>

        <el-table-column prop="sortId" label="排序" width="auto" align="center">
          <template #default="{ row }">
            <el-tag size="small">{{ row.sortId || 0 }}</el-tag>
          </template>
        </el-table-column>

        <el-table-column label="操作" width="auto" align="center">
          <template #default="{ row }">
            <el-button-group>
              <el-button
                v-if="row.pid === 0"
                size="small"
                type="success"
                :icon="Plus"
                @click="handleAdd(row.id)"
                plain
              >
                添加子菜单
              </el-button>
              <el-button size="small" type="primary" :icon="Edit" @click="handleEdit(row)" plain>
                编辑
              </el-button>
              <el-button size="small" type="danger" :icon="Delete" @click="handleDelete(row)" plain>
                删除
              </el-button>
            </el-button-group>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!-- 添加/编辑菜单对话框 -->
    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="500px" @close="handleCancel">
      <el-form
        ref="formRef"
        :model="formData"
        :rules="rules"
        label-width="100px"
        label-position="left"
      >
        <el-form-item label="父级菜单" prop="pid">
          <el-select
            v-model="formData.pid"
            placeholder="请选择父级菜单"
            style="width: 100%"
            :disabled="isEdit"
          >
            <el-option
              v-for="option in getParentMenuOptions(menuList)"
              :key="option.value"
              :label="option.label"
              :value="option.value"
              :disabled="option.disabled"
            />
          </el-select>
        </el-form-item>

        <el-form-item label="菜单名称" prop="name">
          <el-input
            v-model="formData.name"
            placeholder="请输入菜单名称"
            maxlength="50"
            show-word-limit
          />
        </el-form-item>

        <el-form-item label="菜单图标">
          <el-select v-model="formData.icon" placeholder="请选择图标" style="width: 100%" clearable>
            <el-option
              v-for="icon in iconOptions"
              :key="icon.value"
              :label="icon.label"
              :value="icon.value"
            />
          </el-select>
        </el-form-item>

        <el-form-item label="路由地址">
          <el-input
            v-model="formData.route"
            placeholder="请输入路由地址，如：/user"
            maxlength="100"
          />
        </el-form-item>

        <el-form-item label="排序号">
          <el-input-number
            v-model="formData.sortId"
            :min="0"
            :max="999"
            placeholder="排序号"
            style="width: 100%"
          />
        </el-form-item>
      </el-form>

      <template #footer>
        <div class="dialog-footer">
          <el-button @click="handleCancel">取消</el-button>
          <el-button type="primary" @click="handleSave">确定</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<style lang="css" scoped>
.menu-view {
  padding: 24px;
  background: #f5f7fa;
  min-height: calc(100vh - 100px);
}

.page-header {
  margin-bottom: 24px;
}

.page-title {
  margin: 0 0 8px 0;
  font-size: 24px;
  font-weight: 600;
  color: #1f2937;
}

.page-description {
  margin: 0;
  color: #6b7280;
  font-size: 14px;
}

.menu-card {
  margin-bottom: 24px;
  border-radius: 12px;
  border: none;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header-content {
  display: flex;
  align-items: center;
  gap: 8px;
}

.header-icon {
  color: #3b82f6;
  font-size: 20px;
}

.card-title {
  font-size: 18px;
  font-weight: 600;
  color: #1f2937;
}

.menu-name {
  display: flex;
  align-items: center;
  gap: 8px;
}

.menu-icon {
  color: #3b82f6;
  font-size: 16px;
}

.text-muted {
  color: #909399;
  font-size: 14px;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

/* 表格样式优化 */
:deep(.el-table) {
  border-radius: 8px;
  overflow: hidden;
}

:deep(.el-table__header-wrapper) {
  border-radius: 8px 8px 0 0;
}

:deep(.el-table td) {
  border-bottom: 1px solid #f1f5f9;
}

:deep(.el-table tr:hover > td) {
  background-color: #f8fafc !important;
}

/* 树形表格样式 */
:deep(.menu-card .el-table__header th:first-child),
:deep(.menu-card .el-table__body td:first-child) {
  padding-left: 12px;
}

:deep(.menu-card .el-table__header th:first-child .cell) {
  padding-left: 0;
}

:deep(.menu-card .el-table__body td:first-child .cell) {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-left: 0;
}

:deep(.menu-card .el-table__body .el-table__indent),
:deep(.menu-card .el-table__body .el-table__placeholder) {
  width: 12px;
}

:deep(.menu-card .el-table__body .el-table__expand-icon) {
  display: flex;
  align-items: center;
  justify-content: center;
  color: #3b82f6;
  transition: transform 0.2s ease;
}

:deep(.menu-card .el-table__body .el-table__placeholder) {
  color: #909399;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* 按钮样式优化 */
:deep(.el-button--small.is-plain) {
  padding: 5px 12px;
  border-radius: 6px;
}

:deep(.el-button-group .el-button) {
  margin-left: 0;
}

:deep(.el-button-group .el-button:not(:first-child)) {
  margin-left: -1px;
}

/* 标签样式优化 */
:deep(.el-tag) {
  border-radius: 6px;
  font-weight: 500;
}

/* 对话框样式优化 */
:deep(.el-dialog) {
  border-radius: 12px;
}

:deep(.el-dialog__header) {
  padding: 24px 24px 12px 24px;
  border-bottom: 1px solid #f1f5f9;
}

:deep(.el-dialog__body) {
  padding: 24px;
}

:deep(.el-dialog__footer) {
  padding: 12px 24px 24px 24px;
  border-top: 1px solid #f1f5f9;
}

/* 表单样式优化 */
:deep(.el-form-item__label) {
  font-weight: 600;
  color: #374151;
}

:deep(.el-input__wrapper) {
  border-radius: 6px;
}

:deep(.el-select .el-input__wrapper) {
  border-radius: 6px;
}

:deep(.el-input-number .el-input__wrapper) {
  border-radius: 6px;
}

/* 空状态样式优化 */
:deep(.el-empty) {
  padding: 40px 20px;
}

:deep(.el-empty__description) {
  color: #909399;
  font-size: 14px;
}

/* 响应式布局 */
@media (max-width: 768px) {
  .menu-view {
    padding: 16px;
  }

  .card-header {
    flex-direction: column;
    gap: 12px;
    align-items: flex-start;
  }

  :deep(.el-table__body-wrapper) {
    overflow-x: auto;
  }
}
</style>
